/**
 * Created by bdbs on 2017/6/20.
 */
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import style from '../style.scss';
import Dictionary from './Dictionary/Dictionary';

function getSentence(spanDom, sentence = '') {
  let prevDom = spanDom;
  let nextDom = spanDom;
  while (prevDom.previousSibling) {
    if (prevDom.previousSibling.innerText) sentence = prevDom.previousSibling.innerText + ' ' + sentence;
    prevDom = prevDom.previousSibling;
  }
  while (nextDom.nextSibling) {
    if (nextDom.nextSibling.innerText) sentence = sentence + ' ' + nextDom.nextSibling.innerText;
    nextDom = nextDom.nextSibling;
  }
  return sentence;
}

function getSelectionSpan(range) {
  const { startOffset, endOffset } = range;
  const sentence = range.endContainer.data;
  const newCentence = sentence.slice(0, startOffset) + '<em>' + sentence.slice(startOffset, endOffset) + '</em>' + sentence.slice(endOffset);
  return newCentence;
}

class Subtitle extends Component {
  // 构造
  constructor(props) {
    super(props);
    // 初始状态
    this.state = {
      time: 0,
      subtitleTime: 0,
      offsetTime: 0,
      selection: undefined,
    }

    this.currentSentence = undefined;
    this.subtitleTimes = props.subtitle.map(sentence => sentence.time);
  }

  renderSubtitle () {
    return this.props.subtitle.map((sentenceData, index) => {
      let sentenceHTML = `<span>${sentenceData.subtitle.replace(/ /g, '</span> <span>')}</span>`
      if (sentenceData.subtitle2) sentenceHTML = sentenceHTML + `<br/><span>${sentenceData.subtitle2.replace(/ /g, '</span> <span>')}</span>`
      return (
        <p
          onClick={this.handleCentenceClick.bind(this, sentenceData)}
          ref={ 'sentence' + sentenceData.time }
          className={ sentenceData.time === this.state.subtitleTime ? style.active : '' }
          key={index}
          dangerouslySetInnerHTML={{__html: sentenceHTML}}>
        </p>
      )
    });
  }
  
  handleCentenceClick(sentenceData) {
    setTimeout(() => {
      if (!this.state.selection) {
        this.props.onCentenceClick((sentenceData.time - 6 - this.state.offsetTime) / 10);
      }
    }, 400);
  }

  handleOffset(time) {
    this.setState({
      offsetTime: this.state.offsetTime + time,
    });
  }

  shouldComponentUpdate(nextProps, nextState) {
    if (this.props.subtitle !== nextProps.subtitle) {
      this.subtitleTimes = nextProps.subtitle.map(sentence => sentence.time);
      return true;
    }

    console.log('xxxx', nextProps.time + this.state.offsetTime, this.subtitleTimes);
    if (this.subtitleTimes && this.subtitleTimes.indexOf(String(nextProps.time + this.state.offsetTime)) >= 0) {
      if (this.currentSentence) this.currentSentence.className = '';
      this.currentSentence = this.refs['sentence' + (nextProps.time + this.state.offsetTime)];
      this.currentSentence.className = style.active;

      if (this.currentSentence.offsetTop < this.refs.subtitleBox.scrollTop || this.currentSentence.offsetTop > this.refs.subtitleBox.scrollTop + this.refs.subtitleBox.clientHeight - 20) {
        this.refs.subtitleBox.scrollTop = this.currentSentence.offsetTop - 200;
        // this.refs.subtitleBox.scrollTo({
        //   behavior: 'smooth',
        //   top: this.currentSentence.offsetTop - 200,
        // })
      }

    }
    return this.state !== nextState;
  }

  handleMouseDown(e) {
    e.stopPropagation();
    const eventData = {
      clientX: e.clientX,
      clientY: e.clientY + 20,
      target: e.target,
    }
    const cacheWordDom = e.target;
    this.timerBg = setTimeout(() => {
      const selectionText = window.getSelection().toString();
      if (selectionText) return;

      this.cacheWordDom = cacheWordDom;
      this.cacheWordDom.className = style.selected;
      this.timerBg = undefined;
    }, 300);
  }

  handleMouseUp(e) {
    e.stopPropagation();
    const selectionText = window.getSelection().toString();

    if (selectionText) {
      const selection = window.getSelection();
      const range = selection.getRangeAt(0);

      if (selectionText.trim()) {
        this.setState({
          selection: {
            text: selectionText,
            clientX: e.clientX,
            clientY: e.clientY + 20,
            target: e.target,
            sentence: getSentence(e.target, getSelectionSpan(range)),
          },
        });
      }
      return;
    } else if (this.cacheWordDom) {
        this.setState({
          selection: {
            text: this.cacheWordDom.innerText,
            sentence: getSentence(e.target, `<em>${this.cacheWordDom.innerText}</em>`),
          },
        });
    }

    clearTimeout(this.timerBg);
    if (this.cacheWordDom) this.cacheWordDom.className = '';
    this.cacheWordDom = undefined;
  }

  clearSelection() {
    this.setState({
      selection: undefined,
    });
  }

  render() {
    return (
      <div className={ style.subtitle }>
        <div>
          <div><a onClick={this.handleOffset.bind(this, 10)}>+10</a></div>
          <div>{this.state.offsetTime}</div>
          <div><a onClick={this.handleOffset.bind(this, -10)}>-10</a></div>
        </div>
        <div
          ref="subtitleBox"
          className={style.subtitleBox}
          onMouseUp={this.handleMouseUp.bind(this)}
          onMouseDown={this.handleMouseDown.bind(this)}>
          { this.renderSubtitle() }
        </div>
        {!!this.state.selection && (
          <div className={style.modal}>
            <Dictionary
              selection={this.state.selection}
              clearSelection={this.clearSelection.bind(this)}
            />
          </div>
        )}
      </div>
    );
  }
}

Subtitle.defaultProps = {
  onPickWord({ word, sentence, x, y }) {
    console.log('params', word, sentence, x, y);
  },
}

Subtitle.propTypes = {
  subtitle: PropTypes.array.isRequired,
  onCentenceClick: PropTypes.func.isRequired,
}

export default Subtitle;
